package com.dylan.channel.v10.handler;

import com.dylan.channel.v10.attribute.Attribute;
import com.dylan.channel.v10.attribute.AttributeKey;
import com.dylan.channel.v10.channel.Channel;
import com.dylan.channel.v10.future.ChannelFuture;
import com.dylan.channel.v10.future.ChannelPromise;

import java.net.SocketAddress;

public class DefaultChannelPipeline implements ChannelPipeline {

    private final Channel channel;

    /**
     * @Author: PP-jessica
     * @Description:把DefaultChannelPipeline当成一个链表的话，下面两个就是头节点和尾节点
     */
    final AbstractChannelHandlerContext head;
    final AbstractChannelHandlerContext tail;

    public DefaultChannelPipeline(Channel channel) {
        this.channel = channel;
        //创建尾节点
        tail = new TailContext(this);
        //创建头节点
        head = new HeadContext(this);
        //连接成只有两个节点的链表
        //这里暂时使用单向链表
        head.next = tail;
        tail.prev = head;
    }

    @Override
    public ChannelPipeline addFirst(ChannelHandler handler) {
        return null;
    }

    @Override
    public ChannelPipeline addLast(ChannelHandler handler) {
        return null;
    }

    @Override
    public Channel channel() {
        return this.channel;
    }

    @Override
    public ChannelInboundInvoker fireChannelRegistered() {
        return null;
    }

    @Override
    public ChannelInboundInvoker fireChannelUnregistered() {
        return null;
    }

    @Override
    public ChannelInboundInvoker fireChannelActive() {
        return null;
    }

    @Override
    public ChannelInboundInvoker fireChannelInactive() {
        return null;
    }

    @Override
    public ChannelInboundInvoker fireExceptionCaught(Throwable cause) {
        return null;
    }

    @Override
    public ChannelInboundInvoker fireUserEventTriggered(Object event) {
        return null;
    }

    @Override
    public ChannelPipeline fireChannelRead(Object msg) {
        AbstractChannelHandlerContext.invokeChannelRead(head, msg);
        return this;
    }

    @Override
    public ChannelInboundInvoker fireChannelReadComplete() {
        return null;
    }

    @Override
    public ChannelInboundInvoker fireChannelWritabilityChanged() {
        return null;
    }

    @Override
    public ChannelFuture bind(SocketAddress localAddress) {
        return null;
    }

    @Override
    public ChannelFuture connect(SocketAddress remoteAddress) {
        return null;
    }

    @Override
    public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) {
        return null;
    }

    @Override
    public ChannelFuture disconnect() {
        return null;
    }

    @Override
    public ChannelFuture close() {
        return null;
    }

    @Override
    public ChannelFuture deregister() {
        return null;
    }

    @Override
    public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
        return tail.bind(localAddress, promise);
    }

    @Override
    public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) {
        return null;
    }

    @Override
    public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
        return null;
    }

    @Override
    public ChannelFuture close(ChannelPromise promise) {
        return null;
    }

    @Override
    public ChannelOutboundInvoker read() {
        return null;
    }

    @Override
    public ChannelFuture write(Object msg) {
        return null;
    }

    @Override
    public ChannelFuture write(Object msg, ChannelPromise promise) {
        return null;
    }

    @Override
    public ChannelOutboundInvoker flush() {
        return null;
    }

    @Override
    public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
        return null;
    }

    @Override
    public ChannelFuture writeAndFlush(Object msg) {
        return null;
    }

    @Override
    public ChannelPromise newPromise() {
        return null;
    }

    /**
     * @Author: PP-jessica
     * @Description:可以看出尾节点是个入站处理器
     */
    final class TailContext extends AbstractChannelHandlerContext implements ChannelInboundHandler {

        TailContext(DefaultChannelPipeline pipeline) {
            super(pipeline, TailContext.class);
        }

        @Override
        public Channel channel() {
            return pipeline().channel();
        }

        @Override
        public ChannelHandler handler() {
            return this.handler();
        }

        @Override
        public ChannelFuture bind(SocketAddress localAddress) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) {
            return null;
        }

        @Override
        public ChannelFuture disconnect() {
            return null;
        }

        @Override
        public ChannelFuture close() {
            return null;
        }

        @Override
        public ChannelFuture deregister() {
            return null;
        }

        @Override
        public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture close(ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelHandlerContext read() {
            return null;
        }

        @Override
        public ChannelFuture write(Object msg) {
            return null;
        }

        @Override
        public ChannelFuture write(Object msg, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelHandlerContext flush() {
            return null;
        }

        @Override
        public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture writeAndFlush(Object msg) {
            return null;
        }

        @Override
        public ChannelPromise newPromise() {
            return null;
        }


        @Override
        public void channelRegistered(ChannelHandlerContext ctx) {

        }

        @Override
        public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) {

        }

        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {

        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

        }

        @Override
        public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public <T> Attribute<T> attr(AttributeKey<T> key) {
            return null;
        }

        @Override
        public <T> boolean hasAttr(AttributeKey<T> key) {
            return false;
        }

        @Override
        public ChannelInboundInvoker fireChannelRegistered() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelUnregistered() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelActive() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelInactive() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireExceptionCaught(Throwable cause) {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireUserEventTriggered(Object event) {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelReadComplete() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelWritabilityChanged() {
            return null;
        }
    }

    /**
     * @Author: PP-jessica
     * @Description:头节点即是出站处理器，又是入站处理器
     */
    final class HeadContext extends AbstractChannelHandlerContext implements ChannelOutboundHandler, ChannelInboundHandler {

        private final Channel.Unsafe unsafe;

        HeadContext(DefaultChannelPipeline pipeline) {
            super(pipeline, HeadContext.class);
            unsafe = pipeline.channel().unsafe();
        }

        @Override
        public ChannelHandler handler() {
            return handler();
        }

        @Override
        public ChannelFuture bind(SocketAddress localAddress) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) {
            return null;
        }

        @Override
        public ChannelFuture disconnect() {
            return null;
        }

        @Override
        public ChannelFuture close() {
            return null;
        }

        @Override
        public ChannelFuture deregister() {
            return null;
        }

        @Override
        public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture close(ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelHandlerContext read() {
            return null;
        }

        @Override
        public ChannelFuture write(Object msg) {
            return null;
        }

        @Override
        public ChannelFuture write(Object msg, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelHandlerContext flush() {
            return null;
        }

        @Override
        public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
            return null;
        }

        @Override
        public ChannelFuture writeAndFlush(Object msg) {
            return null;
        }

        @Override
        public ChannelPromise newPromise() {
            return null;
        }


        /**
         * @Author: PP-jessica
         * @Description:在这个方法中给channel绑定读事件
         */
        private void readIfIsAutoRead() {
            if (channel.config().isAutoRead()) {
                channel.read();
            }
        }

        @Override
        public <T> Attribute<T> attr(AttributeKey<T> key) {
            return null;
        }

        @Override
        public <T> boolean hasAttr(AttributeKey<T> key) {
            return false;
        }

        @Override
        public void channelRegistered(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

        }

        @Override
        public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public ChannelInboundInvoker fireChannelRegistered() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelUnregistered() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelActive() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelInactive() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireExceptionCaught(Throwable cause) {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireUserEventTriggered(Object event) {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelReadComplete() {
            return null;
        }

        @Override
        public ChannelInboundInvoker fireChannelWritabilityChanged() {
            return null;
        }

        @Override
        public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {

        }

        @Override
        public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception {

        }

        @Override
        public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {

        }

        @Override
        public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {

        }

        @Override
        public void read(ChannelHandlerContext ctx) throws Exception {

        }

        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {

        }

        @Override
        public void flush(ChannelHandlerContext ctx) throws Exception {

        }
    }
}
